package com.example.webclient_code.controller;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * @author kangchen
 * @date 2025/10/9 17:37
 */
@RestController
@RequestMapping("/third")
public class ThirdCodeController {

    private static final Logger logger = LoggerFactory.getLogger(ThirdCodeController.class);

    @GetMapping("/one")
    public Mono<String> getBaiduRobotsMethod(HttpServletResponse response) {
        String baseUrl = "https://www.baidu.com";
        Mono<String> result = WebClient.create(baseUrl)
                .get()
                .uri("/robots.txt")
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .retrieve()
                .bodyToMono(String.class);
        response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
        return result;
    }

    @GetMapping("/two")
    public ResponseEntity<String> getBaiduRobotsTwoMethod(HttpServletResponse response) {
        String baseUrl = "https://www.baidu.com";

        HttpClient httpClient = HttpClient.create()
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
                .doOnConnected(connect -> {
                    connect.addHandlerLast(new ReadTimeoutHandler(10, TimeUnit.SECONDS));
                }).keepAlive(true);
        Mono<byte[]> objectMono = WebClient.builder()
                .baseUrl(baseUrl)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader(HttpHeaders.ACCEPT, MediaType.ALL_VALUE)
                .defaultHeader(HttpHeaders.REFERER, baseUrl)
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .filter(logRequest())
                .build()
                .get()
                .uri("/robots.txt")
                .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE)
                .retrieve()
                .bodyToMono(byte[].class);
        byte[] block = objectMono.block(Duration.ofSeconds(30));
        logger.info("block length:{}", block.length);
        response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_PLAIN_VALUE);
        return ResponseEntity.ok(new String(block, StandardCharsets.UTF_8));
    }

    // 日志拦截器（打印请求信息，方便调试）
    private static ExchangeFilterFunction logRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            logger.info("\n=== Sync Request ===\nURL: {}\nMethod: {}\nHeaders: {}\nBody: {}\n",
                    clientRequest.url(),
                    clientRequest.method(),
                    clientRequest.headers(),
                    clientRequest.body());
            return Mono.just(clientRequest);
        });
    }


}
